using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Runtime.InteropServices;
using PickGold.Charting.Utilities;

namespace PickGold.Charting
{
	[SRDescription("DescriptionAttributeAxisScaleSegment_AxisScaleSegment")]
	internal class AxisScaleSegment
	{
		private double _interval;
		private double _intervalOffset;
		private DateTimeIntervalType _intervalOffsetType;
		private DateTimeIntervalType _intervalType;
		private Stack _oldAxisSettings = new Stack();
		private double _position;
		private double _scaleMaximum;
		private double _scaleMinimum;
		private double _size;
		private double _spacing;
		private object _tag;
		internal Axis axis;

		private GraphicsPath GetBreakLinePath(RectangleF breakLinePosition, bool top)
		{
			var path = new GraphicsPath();
			if (this.axis.ScaleBreakStyle.BreakLineStyle == BreakLineStyle.Wave)
			{
				PointF[] points = null;
				new Random(0x6a5c9);
				int numberOfSegments = 0;
				if ((this.axis.AxisPosition == AxisPosition.Right) || (this.axis.AxisPosition == AxisPosition.Left))
				{
					float x = breakLinePosition.X;
					float right = breakLinePosition.Right;
					float y = top ? breakLinePosition.Y : breakLinePosition.Bottom;
					numberOfSegments = (((int)(right - x)) / 40) * 2;
					if (numberOfSegments < 2)
					{
						numberOfSegments = 2;
					}
					float num5 = (right - x) / ((float)numberOfSegments);
					points = new PointF[numberOfSegments + 1];
					for (int i = 1; i < (numberOfSegments + 1); i++)
					{
						points[i] = new PointF(x + (i * num5), y + (((i % 2) == 0) ? -2f : 2f));
					}
					points[0] = new PointF(x, y);
					points[points.Length - 1] = new PointF(right, y);
				}
				else
				{
					float num7 = breakLinePosition.Y;
					float bottom = breakLinePosition.Bottom;
					float num9 = top ? breakLinePosition.X : breakLinePosition.Right;
					numberOfSegments = (((int)(bottom - num7)) / 40) * 2;
					if (numberOfSegments < 2)
					{
						numberOfSegments = 2;
					}
					float num10 = (bottom - num7) / ((float)numberOfSegments);
					points = new PointF[numberOfSegments + 1];
					for (int j = 1; j < (numberOfSegments + 1); j++)
					{
						points[j] = new PointF(num9 + (((j % 2) == 0) ? -2f : 2f), num7 + (j * num10));
					}
					points[0] = new PointF(num9, num7);
					points[points.Length - 1] = new PointF(num9, bottom);
				}
				path.AddCurve(points, 0, numberOfSegments, 0.8f);
				return path;
			}
			if (this.axis.ScaleBreakStyle.BreakLineStyle == BreakLineStyle.Ragged)
			{
				PointF[] tfArray2 = null;
				Random random = new Random(0x6a5c9);
				if ((this.axis.AxisPosition == AxisPosition.Right) || (this.axis.AxisPosition == AxisPosition.Left))
				{
					float num12 = breakLinePosition.X;
					float num13 = breakLinePosition.Right;
					float num14 = top ? breakLinePosition.Y : breakLinePosition.Bottom;
					float num15 = 10f;
					int num16 = (int)((num13 - num12) / num15);
					if (num16 < 2)
					{
						num16 = 2;
					}
					tfArray2 = new PointF[num16];
					for (int k = 1; k < (num16 - 1); k++)
					{
						tfArray2[k] = new PointF(num12 + (k * num15), num14 + random.Next(-3, 3));
					}
					tfArray2[0] = new PointF(num12, num14);
					tfArray2[tfArray2.Length - 1] = new PointF(num13, num14);
				}
				else
				{
					float num18 = breakLinePosition.Y;
					float num19 = breakLinePosition.Bottom;
					float num20 = top ? breakLinePosition.X : breakLinePosition.Right;
					float num21 = 10f;
					int num22 = (int)((num19 - num18) / num21);
					if (num22 < 2)
					{
						num22 = 2;
					}
					tfArray2 = new PointF[num22];
					for (int m = 1; m < (num22 - 1); m++)
					{
						tfArray2[m] = new PointF(num20 + random.Next(-3, 3), num18 + (m * num21));
					}
					tfArray2[0] = new PointF(num20, num18);
					tfArray2[tfArray2.Length - 1] = new PointF(num20, num19);
				}
				path.AddLines(tfArray2);
				return path;
			}
			if ((this.axis.AxisPosition == AxisPosition.Right) || (this.axis.AxisPosition == AxisPosition.Left))
			{
				if (top)
				{
					path.AddLine(breakLinePosition.X, breakLinePosition.Y, breakLinePosition.Right, breakLinePosition.Y);
					return path;
				}
				path.AddLine(breakLinePosition.X, breakLinePosition.Bottom, breakLinePosition.Right, breakLinePosition.Bottom);
				return path;
			}
			if (top)
			{
				path.AddLine(breakLinePosition.X, breakLinePosition.Y, breakLinePosition.X, breakLinePosition.Bottom);
				return path;
			}
			path.AddLine(breakLinePosition.Right, breakLinePosition.Y, breakLinePosition.Right, breakLinePosition.Bottom);
			return path;
		}

		internal RectangleF GetBreakLinePosition(ChartGraphics graph, AxisScaleSegment nextSegment)
		{
			RectangleF rectangle = this.axis.PlotAreaPosition.ToRectangleF();
			double linearPosition = this.axis.GetLinearPosition(nextSegment.ScaleMinimum);
			double num2 = this.axis.GetLinearPosition(this.ScaleMaximum);
			if ((this.axis.AxisPosition == AxisPosition.Right) || (this.axis.AxisPosition == AxisPosition.Left))
			{
				rectangle.Y = (float)Math.Min(linearPosition, num2);
				rectangle.Height = (float)Math.Max(linearPosition, num2);
			}
			else
			{
				rectangle.X = (float)Math.Min(linearPosition, num2);
				rectangle.Width = (float)Math.Max(linearPosition, num2);
			}
			rectangle = Rectangle.Round(graph.GetAbsoluteRectangle(rectangle));
			if ((this.axis.AxisPosition == AxisPosition.Right) || (this.axis.AxisPosition == AxisPosition.Left))
			{
				rectangle.Height = Math.Abs((float)(rectangle.Y - rectangle.Height));
				rectangle.X -= this.axis.ChartArea.BorderWidth;
				rectangle.Width += 2 * this.axis.ChartArea.BorderWidth;
				return rectangle;
			}
			rectangle.Width = Math.Abs((float)(rectangle.X - rectangle.Width));
			rectangle.Y -= this.axis.ChartArea.BorderWidth;
			rectangle.Height += 2 * this.axis.ChartArea.BorderWidth;
			return rectangle;
		}

		private Brush GetChartFillBrush(ChartGraphics graph)
		{
			Chart chart = this.axis.ChartArea.Common.Chart;
			Brush brush = null;
			if (chart.BackGradientStyle == GradientStyle.None)
			{
				brush = new SolidBrush(chart.BackColor);
			}
			else
			{
				brush = graph.GetGradientBrush(new RectangleF(0f, 0f, (float)(chart.ChartPicture.Width - 1), (float)(chart.ChartPicture.Height - 1)), chart.BackColor, chart.BackSecondaryColor, chart.BackGradientStyle);
			}
			if (chart.BackHatchStyle != ChartHatchStyle.None)
			{
				brush = graph.GetHatchBrush(chart.BackHatchStyle, chart.BackColor, chart.BackSecondaryColor);
			}
			if (((chart.BackImage.Length > 0) && (chart.BackImageWrapMode != ChartImageWrapMode.Unscaled)) && (chart.BackImageWrapMode != ChartImageWrapMode.Scaled))
			{
				brush = graph.GetTextureBrush(chart.BackImage, chart.BackImageTransparentColor, chart.BackImageWrapMode, chart.BackColor);
			}
			return brush;
		}

		internal void GetScalePositionAndSize(double plotAreaSize, out double scalePosition, out double scaleSize)
		{
			scaleSize = (this.Size - this.Spacing) * (plotAreaSize / 100.0);
			scalePosition = this.Position * (plotAreaSize / 100.0);
		}

		internal void PaintBreakLine(ChartGraphics graph, AxisScaleSegment nextSegment)
		{
			RectangleF breakLinePosition = this.GetBreakLinePosition(graph, nextSegment);
			GraphicsPath breakLinePath = this.GetBreakLinePath(breakLinePosition, true);
			GraphicsPath addingPath = null;
			if ((breakLinePosition.Width > 0f) && (breakLinePosition.Height > 0f))
			{
				addingPath = this.GetBreakLinePath(breakLinePosition, false);
				using (GraphicsPath path3 = new GraphicsPath())
				{
					path3.AddPath(breakLinePath, true);
					path3.Reverse();
					path3.AddPath(addingPath, true);
					path3.CloseAllFigures();
					using (Brush brush = this.GetChartFillBrush(graph))
					{
						graph.FillPath(brush, path3);
						if ((this.axis.ChartArea.ShadowOffset != 0) && !this.axis.ChartArea.ShadowColor.IsEmpty)
						{
							RectangleF rect = breakLinePosition;
							if ((this.axis.AxisPosition == AxisPosition.Right) || (this.axis.AxisPosition == AxisPosition.Left))
							{
								rect.Y += this.axis.ChartArea.ShadowOffset;
								rect.Height -= this.axis.ChartArea.ShadowOffset;
								rect.X = rect.Right - 1f;
								rect.Width = this.axis.ChartArea.ShadowOffset + 2;
							}
							else
							{
								rect.X += this.axis.ChartArea.ShadowOffset;
								rect.Width -= this.axis.ChartArea.ShadowOffset;
								rect.Y = rect.Bottom - 1f;
								rect.Height = this.axis.ChartArea.ShadowOffset + 2;
							}
							graph.FillRectangle(brush, rect);
							using (GraphicsPath path4 = new GraphicsPath())
							{
								path4.AddPath(breakLinePath, false);
								float shadowOffset = this.axis.ChartArea.ShadowOffset;
								if ((this.axis.AxisPosition == AxisPosition.Right) || (this.axis.AxisPosition == AxisPosition.Left))
								{
									shadowOffset = Math.Min(shadowOffset, breakLinePosition.Height);
								}
								else
								{
									shadowOffset = Math.Min(shadowOffset, breakLinePosition.Width);
								}
								int num2 = (int)(((float)this.axis.ChartArea.ShadowColor.A) / shadowOffset);
								RectangleF absoluteRectangle = graph.GetAbsoluteRectangle(this.axis.PlotAreaPosition.ToRectangleF());
								if ((this.axis.AxisPosition == AxisPosition.Right) || (this.axis.AxisPosition == AxisPosition.Left))
								{
									absoluteRectangle.X += this.axis.ChartArea.ShadowOffset;
									absoluteRectangle.Width += this.axis.ChartArea.ShadowOffset;
								}
								else
								{
									absoluteRectangle.Y += this.axis.ChartArea.ShadowOffset;
									absoluteRectangle.Height += this.axis.ChartArea.ShadowOffset;
								}
								graph.SetClip(graph.GetRelativeRectangle(absoluteRectangle));
								for (int i = 0; i < shadowOffset; i++)
								{
									using (Matrix matrix = new Matrix())
									{
										if ((this.axis.AxisPosition == AxisPosition.Right) || (this.axis.AxisPosition == AxisPosition.Left))
										{
											matrix.Translate(0f, 1f);
										}
										else
										{
											matrix.Translate(1f, 0f);
										}
										path4.Transform(matrix);
									}
									using (Pen pen = new Pen(Color.FromArgb(this.axis.ChartArea.ShadowColor.A - (num2 * i), this.axis.ChartArea.ShadowColor), 1f))
									{
										graph.DrawPath(pen, path4);
									}
								}
								graph.ResetClip();
							}
						}
					}
				}
			}
			if (this.axis.ScaleBreakStyle.BreakLineStyle != BreakLineStyle.None)
			{
				using (Pen pen2 = new Pen(this.axis.ScaleBreakStyle.LineColor, (float)this.axis.ScaleBreakStyle.LineWidth))
				{
					pen2.DashStyle = graph.GetPenStyle(this.axis.ScaleBreakStyle.LineDashStyle);
					graph.DrawPath(pen2, breakLinePath);
					if ((breakLinePosition.Width > 0f) && (breakLinePosition.Height > 0f))
					{
						graph.DrawPath(pen2, addingPath);
					}
				}
			}
			breakLinePath.Dispose();
			breakLinePath = null;
			if (addingPath != null)
			{
				addingPath.Dispose();
				addingPath = null;
			}
		}

		internal void RestoreAxisScaleAndInterval()
		{
			if (this._oldAxisSettings.Count > 0)
			{
				this.axis.LabelStyle._IntervalOffsetType = (DateTimeIntervalType)this._oldAxisSettings.Pop();
				this.axis.LabelStyle._IntervalOffset = (double)this._oldAxisSettings.Pop();
				this.axis.LabelStyle._IntervalType = (DateTimeIntervalType)this._oldAxisSettings.Pop();
				this.axis.LabelStyle._Interval = (double)this._oldAxisSettings.Pop();
				this.axis.majorTickMark.intervalOffsetType = (DateTimeIntervalType)this._oldAxisSettings.Pop();
				this.axis.majorTickMark.intervalOffset = (double)this._oldAxisSettings.Pop();
				this.axis.majorTickMark.intervalType = (DateTimeIntervalType)this._oldAxisSettings.Pop();
				this.axis.majorTickMark.interval = (double)this._oldAxisSettings.Pop();
				this.axis.majorGrid.intervalOffsetType = (DateTimeIntervalType)this._oldAxisSettings.Pop();
				this.axis.majorGrid.intervalOffset = (double)this._oldAxisSettings.Pop();
				this.axis.majorGrid.intervalType = (DateTimeIntervalType)this._oldAxisSettings.Pop();
				this.axis.majorGrid.interval = (double)this._oldAxisSettings.Pop();
				this.axis.minimum = (double)this._oldAxisSettings.Pop();
				this.axis.maximum = (double)this._oldAxisSettings.Pop();
			}
		}

		internal void SetTempAxisScaleAndInterval()
		{
			if (this._oldAxisSettings.Count == 0)
			{
				this._oldAxisSettings.Push(this.axis.maximum);
				this._oldAxisSettings.Push(this.axis.minimum);
				this._oldAxisSettings.Push(this.axis.majorGrid.interval);
				this._oldAxisSettings.Push(this.axis.majorGrid.intervalType);
				this._oldAxisSettings.Push(this.axis.majorGrid.intervalOffset);
				this._oldAxisSettings.Push(this.axis.majorGrid.intervalOffsetType);
				this._oldAxisSettings.Push(this.axis.majorTickMark.interval);
				this._oldAxisSettings.Push(this.axis.majorTickMark.intervalType);
				this._oldAxisSettings.Push(this.axis.majorTickMark.intervalOffset);
				this._oldAxisSettings.Push(this.axis.majorTickMark.intervalOffsetType);
				this._oldAxisSettings.Push(this.axis.LabelStyle._Interval);
				this._oldAxisSettings.Push(this.axis.LabelStyle._IntervalType);
				this._oldAxisSettings.Push(this.axis.LabelStyle._IntervalOffset);
				this._oldAxisSettings.Push(this.axis.LabelStyle._IntervalOffsetType);
			}
			this.axis.maximum = this.ScaleMaximum;
			this.axis.minimum = this.ScaleMinimum;
			this.axis.majorGrid.interval = this.Interval;
			this.axis.majorGrid.intervalType = this.IntervalType;
			this.axis.majorGrid.intervalOffset = this.IntervalOffset;
			this.axis.majorGrid.intervalOffsetType = this.IntervalOffsetType;
			this.axis.majorTickMark.interval = this.Interval;
			this.axis.majorTickMark.intervalType = this.IntervalType;
			this.axis.majorTickMark.intervalOffset = this.IntervalOffset;
			this.axis.majorTickMark.intervalOffsetType = this.IntervalOffsetType;
			this.axis.LabelStyle._Interval = this.Interval;
			this.axis.LabelStyle._IntervalType = this.IntervalType;
			this.axis.LabelStyle._IntervalOffset = this.IntervalOffset;
			this.axis.LabelStyle._IntervalOffsetType = this.IntervalOffsetType;
		}

		[SRDescription("DescriptionAttributeAxisScaleSegment_Interval"), DefaultValue((double)0.0), SRCategory("CategoryAttributeInterval"), TypeConverter(typeof(AxisIntervalValueConverter))]
		public double Interval
		{
			get
			{
				return this._interval;
			}
			set
			{
				if (double.IsNaN(value))
				{
					this._interval = 0.0;
				}
				else
				{
					this._interval = value;
				}
			}
		}

		[TypeConverter(typeof(AxisIntervalValueConverter)), SRDescription("DescriptionAttributeAxisScaleSegment_IntervalOffset"), SRCategory("CategoryAttributeInterval"), DefaultValue((double)0.0)]
		public double IntervalOffset
		{
			get
			{
				return this._intervalOffset;
			}
		}

		[DefaultValue(0), SRDescription("DescriptionAttributeAxisScaleSegment_IntervalOffsetType"), SRCategory("CategoryAttributeInterval")]
		public DateTimeIntervalType IntervalOffsetType
		{
			get
			{
				return this._intervalOffsetType;
			}
		}

		[SRDescription("DescriptionAttributeAxisScaleSegment_IntervalType"), DefaultValue(0), SRCategory("CategoryAttributeInterval")]
		public DateTimeIntervalType IntervalType
		{
			get
			{
				return this._intervalType;
			}
			set
			{
				if (value == DateTimeIntervalType.NotSet)
				{
					this._intervalType = DateTimeIntervalType.Auto;
				}
				else
				{
					this._intervalType = value;
				}
			}
		}

		[SRCategory("CategoryAttributeMisc"), SRDescription("DescriptionAttributeAxisScaleSegment_Position"), DefaultValue((double)0.0)]
		public double Position
		{
			get
			{
				return this._position;
			}
			set
			{
				if ((value < 0.0) || (value > 100.0))
				{
					throw new ArgumentOutOfRangeException("value", SR.ExceptionAxisScaleSegmentsPositionInvalid);
				}
				this._position = value;
			}
		}

		[DefaultValue((double)0.0), SRCategory("CategoryAttributeMisc"), SRDescription("DescriptionAttributeAxisScaleSegment_ScaleMaximum")]
		public double ScaleMaximum
		{
			get
			{
				return this._scaleMaximum;
			}
			set
			{
				this._scaleMaximum = value;
			}
		}

		[SRCategory("CategoryAttributeMisc"), DefaultValue((double)0.0), SRDescription("DescriptionAttributeAxisScaleSegment_ScaleMinimum")]
		public double ScaleMinimum
		{
			get
			{
				return this._scaleMinimum;
			}
			set
			{
				this._scaleMinimum = value;
			}
		}

		[SRCategory("CategoryAttributeMisc"), SRDescription("DescriptionAttributeAxisScaleSegment_Size"), DefaultValue((double)0.0)]
		public double Size
		{
			get
			{
				return this._size;
			}
			set
			{
				if ((value < 0.0) || (value > 100.0))
				{
					throw new ArgumentOutOfRangeException("value", SR.ExceptionAxisScaleSegmentsSizeInvalid);
				}
				this._size = value;
			}
		}

		[DefaultValue((double)0.0), SRDescription("DescriptionAttributeAxisScaleSegment_Spacing"), SRCategory("CategoryAttributeMisc")]
		public double Spacing
		{
			get
			{
				return this._spacing;
			}
			set
			{
				if ((value < 0.0) || (value > 100.0))
				{
					throw new ArgumentOutOfRangeException("value", SR.ExceptionAxisScaleSegmentsSpacingInvalid);
				}
				this._spacing = value;
			}
		}

		[SRDescription("DescriptionAttributeAxisScaleSegment_Tag"), Browsable(false), SRCategory("CategoryAttributeMisc"), DefaultValue((string)null), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), SerializationVisibility(SerializationVisibility.Hidden)]
		public object Tag
		{
			get
			{
				return this._tag;
			}
			set
			{
				this._tag = value;
			}
		}
	}
}

